package io.xccit.race.controller;

import io.minio.messages.Bucket;
import io.minio.messages.Item;
import io.xccit.race.domain.vo.MinioBucketVO;
import io.xccit.race.domain.vo.MinioObjectVO;
import io.xccit.common.core.controller.BaseController;
import io.xccit.common.core.domain.AjaxResult;
import io.xccit.race.service.MinioService;
import io.xccit.common.utils.file.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;

/**
 * MinIO 管理
 */
@RestController
@RequestMapping("/race/minio")
public class MinioController extends BaseController {

    @Autowired
    private MinioService minioService;

    private static final String FILE_DELIMETER = ",";

    @PostMapping("/upload")
    public AjaxResult upload(@RequestParam("file") MultipartFile file) throws Exception {
        String url = minioService.upload(file);
        String fileName = FileUtils.getName(file.getOriginalFilename());
        AjaxResult ajax = AjaxResult.success();
        ajax.put("url", url);
        ajax.put("fileName", fileName);
        return ajax;
    }

    @PostMapping("/uploads")
    public AjaxResult uploads(@RequestParam("files") List<MultipartFile> files) throws Exception {
        List<String> urls = new ArrayList<String>();
        List<String> fileNames = new ArrayList<String>();
        List<String> newFileNames = new ArrayList<String>();
        List<String> originalFilenames = new ArrayList<String>();
        for (MultipartFile file : files) {
            String url = minioService.upload(file);
            urls.add(url);
            fileNames.add(file.getOriginalFilename());
            newFileNames.add(FileUtils.getName(url));
            originalFilenames.add(file.getOriginalFilename());
        }
        AjaxResult ajax = AjaxResult.success();
        ajax.put("urls", String.join(FILE_DELIMETER, urls));
        ajax.put("fileNames", String.join(FILE_DELIMETER, fileNames));
        ajax.put("newFileNames", String.join(FILE_DELIMETER, newFileNames));
        ajax.put("originalFilenames", String.join(FILE_DELIMETER, originalFilenames));
        return ajax;
    }

    @PostMapping("/uploadTo")
    public AjaxResult uploadToBucket(@RequestParam("bucket") String bucket,
                                     @RequestParam("file") MultipartFile file) throws Exception {
        String url = minioService.uploadToBucket(bucket, file);
        AjaxResult ajax = AjaxResult.success();
        ajax.put("url", url);
        ajax.put("fileName", file.getOriginalFilename());
        return ajax;
    }

    @GetMapping("/buckets")
    public AjaxResult listBuckets() throws Exception {
        List<Bucket> buckets = minioService.listBuckets();
        List<MinioBucketVO> list = new ArrayList<>();
        for (Bucket b : buckets) {
            list.add(new MinioBucketVO(b.name(), b.creationDate()));
        }
        return AjaxResult.success(list);
    }

    @PostMapping("/bucket")
    public AjaxResult createBucket(@RequestParam("bucket") String bucket) throws Exception {
        minioService.createBucket(bucket);
        return AjaxResult.success();
    }

    @DeleteMapping("/bucket/{bucket}")
    public AjaxResult deleteBucket(@PathVariable("bucket") String bucket) throws Exception {
        minioService.deleteBucket(bucket);
        return AjaxResult.success();
    }

    @GetMapping("/objects")
    public AjaxResult listObjects(@RequestParam("bucket") String bucket,
                                  @RequestParam(value = "prefix", required = false) String prefix,
                                  @RequestParam(value = "recursive", required = false, defaultValue = "true") boolean recursive) throws Exception {
        List<Item> items = minioService.listObjects(bucket, prefix, recursive);
        List<MinioObjectVO> list = new ArrayList<>();
        for (Item it : items) {
            String name = it.objectName();
            long size = it.size();
            list.add(new MinioObjectVO(name, size, it.lastModified()));
        }
        return AjaxResult.success(list);
    }

    @DeleteMapping("/object")
    public AjaxResult deleteObject(@RequestParam("bucket") String bucket,
                                   @RequestParam("object") String object) throws Exception {
        boolean ok = minioService.deleteObject(bucket, object);
        return ok ? AjaxResult.success() : AjaxResult.error("删除失败");
    }

    @GetMapping("/presign")
    public AjaxResult getPresign(@RequestParam("bucket") String bucket,
                                 @RequestParam("object") String object,
                                 @RequestParam(value = "expires", required = false, defaultValue = "3600") int expires) throws Exception {
        String url = minioService.getPresignedUrl(bucket, object, expires);
        return AjaxResult.success(url);
    }
}


